package gang.org.springframework.framework.support;

import gang.org.springframework.framework.bean.GangBeanUtils;
import gang.org.springframework.framework.bean.GangRootBeanDefinition;
import gang.org.springframework.framework.factory.GangBeanFactory;
import lombok.SneakyThrows;

import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;

/**
 * @author gang.chen
 * @Date 2021/8/25 13:17
 */
public class GangSimpleInstantiationStrategy implements GangInstantiationStrategy{
    @SneakyThrows
    @Override
    public Object instantiate(GangRootBeanDefinition bd, String beanName, GangBeanFactory owner) {
        /*
         * 业务意义
         * 1）CGLIB 未对Class进行重写
         * 场景一
         * */
        if (!bd.hasMethodOverrides()) {
            Constructor<?> constructorToUse;
            synchronized (bd.constructorArgumentLock) {
                constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    Class<?> clazz = bd.getBeanClass();
                    if (clazz.isInterface()) {
                        System.out.println("throw exception ...");
                    }
                    try {
                        if (false){
                            //TODO
                        }
                        else{
                            constructorToUse = clazz.getDeclaredConstructor();
                        }
                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
            return GangBeanUtils.instantiateClass(constructorToUse);
        }
        else{
            /*
             * 业务意义
             * 1）CGLIB 已对Class进行重写
             * 场景二
             * */
            return null;
        }
    }


    /**
     * 业务意义
     * 1）创建 GangResourceUrlProvider 实例
     * 2）通过 JAVA 反射
     * */
    @Override
    public Object instantiate(GangRootBeanDefinition md, String beanName, GangBeanFactory owner, Object factoryBean, Method factoryMethod, Object... args) {
        try{
            if (false) {
                //TODO
            }else {
                //ReflectionUtil.makeAccessible();
            }
            try{
                /*
                 * 业务意义
                 * 问题1）factoryMethod 该方法指向什么对象
                 *
                 * 问题2）factoryBean 该实例指向什么对象
                 * */
                Object result = factoryMethod.invoke(factoryBean, args);

                return  result;
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @SneakyThrows
    @Override
    public Object instantiate(GangRootBeanDefinition md, String beanName, GangBeanFactory owner, Constructor<?> ctor, Object... args) {
        if (true){

            if (false){
                //TODO
            }
            return GangBeanUtils.instantiateClass(ctor, args);

        }else {
            //TODO
            return null;
        }
    }
}
